package com.unknowpupil.web.component.wallet.transfer;

import com.unknowpupil.web.component.wallet.factory.Web3jFactory;
import com.unknowpupil.web.utils.TransStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.web3j.crypto.Credentials;
import org.web3j.crypto.RawTransaction;
import org.web3j.crypto.TransactionEncoder;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.response.EthGetTransactionCount;
import org.web3j.protocol.core.methods.response.EthSendTransaction;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.protocol.http.HttpService;
import org.web3j.tx.Transfer;
import org.web3j.utils.Convert;
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;

/**
 * @Classname: TransferAccounts
 * @Author: <a> w10g </a>
 * @CreateDate: Create in 2019/10/20 5:15
 * @Description: 转账
 * @Version: 1.0
 */
public class TransferAccounts {
    private final static Web3j web3j = Web3jFactory.build();
   private final static Logger logger = LoggerFactory.getLogger(TransferAccounts.class);

    //默认转账，不设置矿工费
    public static void transfer(String toAddress,String fromKey,double value){
        //通过提供的Transfer进行转账
        TransactionReceipt transactionReceipt = null;
        //转出账户
        Credentials credentials1  = Credentials.create(fromKey);
        try {
            transactionReceipt = Transfer.sendFunds( web3j, credentials1, toAddress, BigDecimal.valueOf(value), Convert.Unit.ETHER).send();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 无需备注
     * @param toAddress
     * @param fromKey
     * @param value
     * @param gasValue
     * @param desc
     */
    public static void transfer(String toAddress,String fromKey,double value,double gasValue,String desc) {
        //转出账户
        Credentials credentials1 = Credentials.create(fromKey);
        //获取当前账户的下一个有效随机数 此处的address为当前钱包的地址
        try {
            //这个方法就是自动加的，不需要自己存了。。
            EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount(credentials1.getAddress(), DefaultBlockParameterName.LATEST).send();
            BigInteger nonce = ethGetTransactionCount.getTransactionCount();

            BigInteger bigAmount = Convert.toWei(value + "", Convert.Unit.ETHER).toBigInteger();
            BigInteger bigGas = Convert.toWei(gasValue + "", Convert.Unit.GWEI).toBigInteger();
            //创建交易  交易序号，gas ，gaslimit ，address，value；
            RawTransaction rawTransaction = RawTransaction.createEtherTransaction(nonce, bigGas, Convert.toWei("21000", Convert.Unit.WEI).toBigInteger(), toAddress, bigAmount);

            // 签名交易 并转换为16进制
            byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials1);
            String hexValue = Numeric.toHexString(signedMessage);
            //发送交易 发送完了或获取一个交易的hash值，这个值可以在区块链浏览器上查询当前交易的结果
            EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();
            if(ethSendTransaction.hasError()){
                logger.info("ETH交易失败:",ethSendTransaction);
            }else{
                String transactionHash = ethSendTransaction.getTransactionHash();
                logger.info("ETH交易成功{}",transactionHash);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 有备注的签名
     * @param toAddress
     * @param fromKey
     * @param value
     * @param gasValue
     * @param desc
     */
    public static void transferStr(String toAddress,String fromKey,double value,double gasValue,String desc){
        //转出账户
        Credentials credentials1  = Credentials.create(fromKey);
        //获取当前账户的下一个有效随机数 此处的address为当前钱包的地址
        try {
            //这个方法就是自动加的，不需要自己存了。。
            EthGetTransactionCount ethGetTransactionCount = web3j.ethGetTransactionCount( credentials1.getAddress(), DefaultBlockParameterName.LATEST).send();
            BigInteger nonce = ethGetTransactionCount.getTransactionCount();

            BigInteger bigAmount=Convert.toWei(value+"", Convert.Unit.ETHER).toBigInteger();
            BigInteger bigGas=Convert.toWei(gasValue+"", Convert.Unit.GWEI).toBigInteger();
            //创建交易  交易序号，gas ，gaslimit ，address，value；
            //desc 需要进行16进制转换
            RawTransaction rawTransaction =RawTransaction.createTransaction(nonce,bigGas,Convert.toWei("21000", Convert.Unit.WEI).toBigInteger(), toAddress,bigAmount, TransStringUtils.str2HexStr(desc));

            // 签名交易 并转换为16进制
            byte[] signedMessage = TransactionEncoder.signMessage(rawTransaction, credentials1);
            String hexValue = Numeric.toHexString(signedMessage);
            //发送交易 发送完了或获取一个交易的hash值，这个值可以在区块链浏览器上查询当前交易的结果
            EthSendTransaction ethSendTransaction = web3j.ethSendRawTransaction(hexValue).send();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }


}
